SRC = ./src
BUILD = ./build
INFO = ./info
INCLUDE = ./src/include
NEWLIB_INCLUDE = ./newlib/include
CFLAGS = -gdwarf-2 -c -O0 -m32 -I$(INCLUDE) -I${NEWLIB_INCLUDE} -fno-pie -fno-stack-protector -nostdlib -nostdinc
TOOL_PREFIX = x86_64-elf-

$(BUILD)/%.o: $(SRC)/%.c
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)gcc $(CFLAGS) $< -o $@

$(BUILD)/%.o: $(SRC)/%.S
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)gcc $(CFLAGS) $< -o $@

.PHONY: boot
boot: $(BUILD)/boot/start.o \
		$(BUILD)/boot/boot.o
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)ld -m elf_i386 -Ttext=0x7c00 $^ -o $(BUILD)/boot.elf
	${TOOL_PREFIX}objcopy -O binary $(BUILD)/boot.elf $(BUILD)/boot.bin
	
.PHONY: kernel
kernel: $(BUILD)/kernel/start.o \
		$(BUILD)/kernel/kernel.o \
		$(BUILD)/kernel/memory.o \
		$(BUILD)/kernel/tty.o \
		$(BUILD)/kernel/global.o \
		$(BUILD)/kernel/kernel32.o
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)ld -m elf_i386 -Ttext=0x8000 $^ -o $(BUILD)/kernel.elf
	${TOOL_PREFIX}objcopy -O binary $(BUILD)/kernel.elf $(BUILD)/kernel.bin

.PHONY: kernel32
kernel32: $(BUILD)/kernel32/start.o \
	$(BUILD)/kernel32/os.o \
	$(BUILD)/kernel32/init/init.o \
	$(BUILD)/kernel32/init/init_entry.o \
	$(BUILD)/kernel32/interrupt.o \
	$(BUILD)/kernel32/pic.o \
	$(BUILD)/kernel32/timer.o \
	$(BUILD)/kernel32/task.o \
	$(BUILD)/kernel32/global32.o \
	$(BUILD)/kernel32/semaphore.o \
	$(BUILD)/kernel32/mutex.o \
	$(BUILD)/kernel32/memory32.o \
	$(BUILD)/kernel32/fs/fs.o \
	$(BUILD)/lib/logf.o \
	$(BUILD)/lib/assert.o \
	$(BUILD)/lib/string.o \
	$(BUILD)/lib/list.o \
	$(BUILD)/lib/bitmap.o \
	$(BUILD)/lib/syscall.o \
	$(BUILD)/kernel32/fs/disk.o
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)ld -m elf_i386 -T $(SRC)/kernel32.lds $^ -o $(BUILD)/os.elf
	${TOOL_PREFIX}objcopy -S $(BUILD)/os.elf $(BUILD)/kernel32.elf

.PHONY: libapp
libapp: $(BUILD)/libapp/crt0.o \
		$(BUILD)/libapp/cstart.o
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)ar -crv $(BUILD)/libapp/$@.a $^

.PHONY: shell
shell: $(BUILD)/shell/main.o
	$(shell mkdir -p $(dir $@))
	$(TOOL_PREFIX)ld -m elf_i386 -T $(SRC)/shell.lds $^ -o $(BUILD)/shell.elf -L $(BUILD)/libapp/ -lapp

.PHONY: all
all: boot kernel kernel32 libapp shell
	$(shell mkdir -p $(INFO))
	dd if=$(BUILD)/boot.bin of=disk.img bs=512
	${TOOL_PREFIX}readelf -a $(BUILD)/kernel.elf > $(INFO)/kernel.txt
	dd if=$(BUILD)/kernel.bin of=disk.img bs=512 seek=1
	${TOOL_PREFIX}readelf -a $(BUILD)/os.elf > $(INFO)/os.txt
	dd if=$(BUILD)/kernel32.elf of=disk.img bs=512 seek=10
	${TOOL_PREFIX}readelf -a $(BUILD)/shell.elf > $(INFO)/shell.txt
	dd if=$(BUILD)/shell.elf of=disk.img bs=512 seek=5000

.PHONY: clean
clean:
	$(shell rm -rf $(BUILD) $(INFO))

.PHONY: bochs
bochs: clean all
	bochsdbg -q -f bochsrc.bxrc -unlock

.PHONY: qemu
qemu: clean all
	qemu-system-i386 -m 128M -s -S -serial stdio -drive file=disk.img,index=0,media=disk,format=raw